package tech.konata.styleslite.rendering.shaders;

import net.minecraft.client.Minecraft;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.Resource;
import net.minecraft.server.packs.resources.ResourceProvider;
import net.minecraft.server.packs.resources.SimpleResource;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class CustomResourceProvider implements ResourceProvider {

    public static final CustomResourceProvider INSTANCE = new CustomResourceProvider();

    private final String rectangle_json =
            """
            {
              "blend": {
                "func": "add",
                "srcrgb": "srcalpha",
                "dstrgb": "1-srcalpha"
              },
              "vertex": "position",
              "fragment": "konata:rectangle",
              "attributes": [],
              "samplers": [],
              "uniforms": [
                { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
                { "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
                { "name": "color1", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] },
                { "name": "color2", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] },
                { "name": "color3", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] },
                { "name": "color4", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] },
                { "name": "uSize", "type": "float", "count": 2, "values": [ 1.0, 1.0 ] },
                { "name": "uLocation", "type": "float", "count": 2, "values": [ 1.0, 1.0 ] },
                { "name": "radius", "type": "float", "count": 1, "values": [ 1.0] }
              ]
            }
            """;

    private final String rectangle_fsh =
            """
            #version 150
                        
            uniform vec4 color1;
            uniform vec4 color2;
            uniform vec4 color3;
            uniform vec4 color4;
                        
            uniform vec2 uSize;
            uniform vec2 uLocation;
            uniform float radius;
                        
            out vec4 fragColor;
                        
            float roundedBoxSDF(vec2 center, vec2 size, float radius) {
                return length(max(abs(center) - size + radius, 0.0)) - radius;
            }
                        
            vec3 createGradient(vec2 coords, vec3 color1, vec3 color2, vec3 color3, vec3 color4){
                vec3 color = mix(mix(color1.rgb, color2.rgb, coords.y), mix(color3.rgb, color4.rgb, coords.y), coords.x);
                color += mix(0.0019607843, -0.0019607843, fract(sin(dot(coords.xy, vec2(12.9898, 78.233))) * 43758.5453));
                return color;
            }
                        
            void main() {
                float distance = roundedBoxSDF(gl_FragCoord.xy - uLocation - (uSize / 2.0), uSize / 2.0, radius);
                float smoothedAlpha = (1.0 - smoothstep(-1.0, 1.0, distance)) * color1.a;
                fragColor = vec4(createGradient((gl_FragCoord.xy - uLocation) / uSize, color1.rgb, color2.rgb, color3.rgb, color4.rgb), smoothedAlpha);
            }
            """;

    private final String blur_json =
            """
            {
              "blend": {
                "func": "add",
                "srcrgb": "srcalpha",
                "dstrgb": "1-srcalpha"
              },
              "vertex": "position",
              "fragment": "konata:blur",
              "attributes": [],
              "samplers": [
                { "name": "InputSampler" }
              ],
              "uniforms": [
                { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
                { "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
                { "name": "InputResolution", "type": "float", "count": 2, "values": [ 1.0, 1.0 ] },
                { "name": "Quality", "type": "float", "count": 1, "values": [ 1.0] },
                { "name": "Brightness", "type": "float", "count": 1, "values": [ 1.0] },
                { "name": "color1", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] },
                { "name": "uSize", "type": "float", "count": 2, "values": [ 1.0, 1.0 ] },
                { "name": "uLocation", "type": "float", "count": 2, "values": [ 1.0, 1.0 ] },
                { "name": "radius", "type": "float", "count": 1, "values": [ 1.0] }
              ]
            }
            """;

    private final String blur_fsh =
            """
            #version 150
                        
            uniform sampler2D InputSampler;
            uniform vec2 InputResolution;
            uniform vec2 uSize;
            uniform vec2 uLocation;
                        
            uniform float radius;
            uniform float Brightness;
            uniform float Quality;
            uniform vec4 color1;
            in vec2 texCoord;
                        
            out vec4 fragColor;
                        
            float roundedBoxSDF(vec2 center, vec2 size, float radius) {
                return length(max(abs(center) - size + radius, 0.0)) - radius;
            }
                        
            vec4 blur() {
                #define TAU 6.28318530718
                        
                vec2 Radius = Quality / InputResolution.xy;
                        
                vec2 uv = gl_FragCoord.xy / InputResolution.xy;
                vec4 Color = texture(InputSampler, uv);
                        
                float step =  TAU / 16.0;
                        
                for (float d = 0.0; d < TAU; d += step) {
                    for (float i = 0.2; i <= 1.0; i += 0.2) {
                        Color += texture(InputSampler, uv + vec2(cos(d), sin(d)) * Radius * i);
                    }
                }
                        
                Color /= 80;
                return (Color + color1) * Brightness;
            }
                        
            void main() {
                vec2 halfSize = uSize / 2.0;
                float smoothedAlpha =  (1.0 - smoothstep(0.0, 1.0, roundedBoxSDF(gl_FragCoord.xy - uLocation - halfSize, halfSize, radius)));
                fragColor = vec4(blur().rgb, smoothedAlpha);
            }        
            """;



    @Override
    public Resource getResource(ResourceLocation p_143935_) throws IOException {

        if (p_143935_.getNamespace().equals("konata")) {

            String resourceStr = this.getResourceString(p_143935_.getPath());

            ByteArrayInputStream bais = new ByteArrayInputStream(resourceStr.getBytes(StandardCharsets.UTF_8));

            return new SimpleResource("I_WANT_TO_LOAD_SOME_RESOURCES_INSIDE_MY_JAR_FILE", p_143935_, bais, null);
        } else {
            return Minecraft.getInstance().getResourceManager().getResource(p_143935_);
        }

    }

    private String getResourceString(String path) {

        switch (path) {

            case "shaders/core/rectangle.json" -> {
                return rectangle_json;
            }

            case "shaders/core/rectangle.fsh" -> {
                return rectangle_fsh;
            }

        }

        return "";
    }

}
